<template>
  <div ref="editorContainer" :class="[fullScreen === true ? 'screen editor' : 'editor']"/>
</template>

<script>
// import * as monaco from 'monaco-editor'
import { editor as monacoEditor, languages as monacoLanguages } from 'monaco-editor'
// import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api'
// 1. 引入monaco-editor中的sql文件
import { language as sqlLanguage } from 'monaco-editor/esm/vs/basic-languages/sql/sql.js'
import { getFillAllByVersion } from '../api/documentManage'
import { showKeyName } from './QuickCode.js'


let cetcLanguage = []
export default {
  // name: 'MonacoEditor',
  props: {
    code: { type: String, default: '' }
  },
  data() {
    return {
      editor: null,
      theme: 'vs-dark',
      value: '',
      registerObject: null,
      keyValue: [],
      fullScreen: false,
      selection: '',
    }
  },
  watch: {
    code: {
      handler(newValue) {
        this.code = newValue
        this.editor.dispose() // 销毁实例
        this.value = newValue
        this.init()
      }
    }
  },
  mounted() {
    this.initMonacoRegister()
    this.getFill()
    this.init()
    document.addEventListener('keydown', this.escEvent)
  },
  beforeDestroy() {
    document.removeEventListener('keydown', this.escEvent)
  },
  destroyed() {
    this.initMonacoRegister()
    // this.registerObject && this.registerObject.dispose()
    // this.editor && this.editor.dispose()
  },
  // get hints() {
  //   const arr = []
  //   // .... //根据需求实时获取提示项
  //   return arr
  // },
  methods: {
    getSelection() {
      return this.selection;
    },
    initMonacoRegister() {
      this.registerObject && this.registerObject.dispose()
      this.editor && this.editor.dispose()
    },
    escEvent(event) {
      if (event.keyCode === 83 && event.ctrlKey) {
        event.preventDefault()
        this.getQuick('Ctrl + S')
        return
      }
      const str = showKeyName(window.event)
      if (str !== '无') this.keyValue.push(str)
      this.keyValue.forEach((i, index) => {
        if (i === 'Alt' && index !== 0) {
          const item = i
          if (this.keyValue[0] !== 'Ctrl' && this.keyValue[0] !== 'Shift') {
            this.keyValue.splice(index, 1)
            this.keyValue.unshift(item)
          } else if (this.keyValue[0] === 'Ctrl') {
            if (this.keyValue[1] === 'Shift') {
              this.keyValue.splice(index, 1)
              this.keyValue.splice(2, 0, item)
            } else {
              this.keyValue.splice(index, 1)
              this.keyValue.splice(1, 0, item)
            }
          } else if (this.keyValue[0] === 'Shift') {
            this.keyValue.splice(index, 1)
            this.keyValue.splice(1, 0, item)
          }
        }
        if (i === 'Shift' && index !== 0) {
          if (this.keyValue[0] !== 'Ctrl') {
            const item = i
            this.keyValue.splice(index, 1)
            this.keyValue.unshift(item)
          } else {
            const item = i
            this.keyValue.splice(index, 1)
            this.keyValue.splice(1, 0, item)
          }
        }
        if (i === 'Ctrl' && index !== 0) {
          const item = i
          this.keyValue.splice(index, 1)
          this.keyValue.unshift(item)
        }
      })
      if (
        this.keyValue.length > 1 ||
        this.keyValue[0] === 'F1' ||
        this.keyValue[0] === 'F2' ||
        this.keyValue[0] === 'F7' ||
        this.keyValue[0] === 'Esc'
      ) {
        const keyName = this.keyValue.join('+')
        this.getQuick(keyName)
      }
      setTimeout(() => {
        this.keyValue = []
      }, 500)
    },
    getQuick(str) {
      console.log(str)
      if (str === 'F2') {
        this.fullScreen = true
        return
      }
      if (str === 'Esc' || str === 'Ctrl + S' || str === 'Alt + 2') {
        this.fullScreen = false
      }
      this.$emit('getQuick', str)
    },
    async getFill() {
      cetcLanguage = []
      if (cetcLanguage.length > 0) {
        return
      }
      const result = await getFillAllByVersion({
        pageNum: 1,
        pageSize: 100,
        version: ''
      })
      if (result) {
        cetcLanguage = result
      }
      // cetcLanguage.filter((item) => {
      //   console.log('item=====', item)
      //   return item.name === 'create.catalog.hive'
      // })
      console.log('=====cetcLanguage======', monacoLanguages, this.registerObject)
      // 提示项设值
      this.registerObject = monacoLanguages && monacoLanguages.registerCompletionItemProvider('*', {
        provideCompletionItems: function(firstParam, secondParam) {
          const suggestions = []
          sqlLanguage.keywords.forEach((item) => {
            suggestions.push({
              label: item,
              kind: monacoLanguages.CompletionItemKind.Keyword,
              insertText: item
            })
          })
          sqlLanguage.operators.forEach((item) => {
            suggestions.push({
              label: item,
              kind: monacoLanguages.CompletionItemKind.Operator,
              insertText: item
            })
          })
          sqlLanguage.builtinFunctions.forEach((item) => {
            suggestions.push({
              label: item,
              kind: monacoLanguages.CompletionItemKind.Function,
              insertText: item
            })
          })
          sqlLanguage.builtinVariables.forEach((item) => {
            suggestions.push({
              label: item,
              kind: monacoLanguages.CompletionItemKind.Variable,
              insertText: item
            })
          })

          if (cetcLanguage.length > 0) {
            cetcLanguage.forEach((item) => {
              suggestions.push({
                label: item.name,
                kind:
                  item.fcategory === 'Variable'
                    ? monacoLanguages.CompletionItemKind.Variable
                    : item.fcategory === 'Function'
                      ? monacoLanguages.CompletionItemKind.Variable
                      : item.fcategory === 'Module'
                        ? monacoLanguages.CompletionItemKind.Module
                        : item.fcategory === 'Operator'
                          ? monacoLanguages.CompletionItemKind.Operator
                          : monacoLanguages.CompletionItemKind.Keyword,
                insertText: item.fillValue
              })
            })
          }
          return {
            suggestions: suggestions,
            firstParam
          }
        }
      })
    },
    init() {
      // 初始化编辑器
      this.editor = monacoEditor.create(this.$refs.editorContainer, {
        value: this.code,
        language: 'sql',
        tabSize: 2,
        automaticLayout: true, // 自动布局
        readOnly: false,
        theme: this.theme,
        foldingStrategy: 'indentation', // 代码可分⼩段折叠
        autoClosingBrackets: 'always',
        folding: true, // 是否启⽤代码折叠
        scrollBeyondLastLine: true, // 设置编辑器是否可以滚动到最后⼀⾏之后
        renderLineHighlight: 'all', // 当前⾏突出显⽰⽅式  "all" | "line" | "none" | "gutter"
        allowNonTsExtensions: true,
        accessibilitySupport: 'on'
      })
      // 监听内容变化
      this.editor.onDidChangeModelContent((e) => {
        this.caretOffset = e.changes[0].rangeOffset // 获取光标位置
        this.value = this.editor.getValue() // 使value和其值保持一致
        this.$emit('changeCode', this.value)
      })

      // 监听失去焦点事件
      this.editor.onDidBlurEditorText((e) => {
        // console.log(e)
      })

      this.editor.onDidChangeCursorPosition((e) => {
        console.log('onDidChangeCursorPosition', e);
        // 获取当前选择范围
        const selection = this.editor.getSelection();
        // 如果有选中的文本，执行相关操作
        this.selection = this.editor.getModel().getValueInRange(selection);
    });
    },
    // 获取编辑框内容
    getCodeContext() {
      return this.editor.getValue()
    },
    // 自动格式化代码
    format() {
      this.editor.trigger('anything', 'editor.action.formatDocument')
      // 或者
      // this.editor.getAction(['editor.action.formatDocument']).run()
    },
    changeEditor() {
      if (this.editor === null) {
        this.init()
      }

      const oldModel = this.editor.getModel()
      const newModel = monacoEditor.createModel(this.code, 'sql')

      if (oldModel) {
        oldModel.dispose()
      }
      this.editor.setModel(newModel)
    }
  }
}
</script>

<style scoped lang="less">
.editor {
  width: 100%;
  height: 100%;
  :deep(.codicon-find-collapsed:before) {
    content: '＞';
  }
  :deep(.codicon-find-expanded:before) {
    content: '﹀';
  }
  :deep(.codicon-case-sensitive:before) {
    content: 'Aa';
    font-size: 14px;
  }
  :deep(.codicon-whole-word:before) {
    content: 'Ab|';
    font-size: 13px;
  }
  :deep(.codicon-preserve-case:before) {
    content: 'AB';
    font-size: 13px;
  }
  :deep(.codicon-regex:before) {
    content: '*';
  }
  :deep(.codicon-find-previous-match:before) {
    content: '↑';
  }
  :deep(.codicon-find-next-match:before) {
    content: '↓';
  }
  :deep(.codicon-find-selection:before) {
    content: '≢';
  }
  :deep(.codicon-widget-close:before) {
    content: '✖';
  }
  :deep(.codicon-find-replace) {
    width: 33px;
  }
  :deep(.codicon-find-replace:before) {
    content: 'b→c';
    font-size: 13px;
  }
  :deep(.codicon-find-replace-all) {
    margin-left: 14px;
  }
  :deep(.codicon-find-replace-all:before) {
    content: 'ab→ac';
    font-size: 13px;
  }
}
.screen {
  position: fixed;
  z-index: 9999;
  width: 100%;
  left: 0;
  top: 0;
  height: 100%;
}
</style>
